from flask import render_template, current_app, abort, g, request, jsonify

from info import constants, db
from info.news import news_blue
from info.models import News, Comment, CommentLike, User
from info.utils.common import user_login_data
from info.utils.response_code import RET


@news_blue.route('/<int:news_id>')
@user_login_data
def news_detail(news_id):
    news_list = None
    try:
        news_list = News.query.filter(News.title.startswith('$$$isDeleted$$$') == False).order_by(
            News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)

    click_news_list = []
    for news_element in news_list if news_list else []:
        click_news_list.append(news_element.to_basic_dict())

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)

    if not news:
        # 返回数据未找到的页面
        abort(404)

    news.clicks += 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()

    comments = None
    try:
        comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)

    comment_like_ids = []
    if g.user:
        try:
            comment_ids = [comment.id for comment in comments]
            if len(comment_ids) > 0:
                comment_likes = CommentLike.query.filter(CommentLike.comment_id.in_(comment_ids),
                                                         CommentLike.user_id == g.user.id).all()
                comment_like_ids = [i.comment_id for i in comment_likes]
        except Exception as e:
            current_app.logger.error(e)

    delete_count = 0
    comments_list =[]
    for item in comments:
        comment_dict = item.to_dict()
        if comment_dict['content'].startswith('$$$isDeleted$$$') or comment_dict['user']['mobile'].startswith('$'):
            delete_count += 1
            continue
        comment_dict['is_like'] = False
        if g.user and item.id in comment_like_ids:
            comment_dict['is_like'] = True
        comments_list.append(comment_dict)

    is_collected = False
    is_followed = False

    user_info = None
    if g.user:
        user = g.user
        if news in user.collection_news:
            is_collected = True
        author = User.query.get(news.user_id)
        if author and author.followers.filter(User.id == user.id).count() > 0:
            is_followed = True
        user_info = user.to_dict()
        if user.is_admin:
            user_info['is_admin'] = True

    data = {
        "news": news.to_dict(),
        "user_info": user_info,
        "click_news_list": click_news_list,
        "is_collected": is_collected,
        "is_followed": is_followed,
        "comments": comments_list,
        "delete_count": delete_count
    }

    return render_template('news/detail.html', data=data)


@news_blue.route('/news_collect', methods=['POST'])
@user_login_data
def news_collect():
    user = g.user
    json_data = request.json
    news_id = json_data.get("news_id")
    action = json_data.get("action")

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    if not news_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ["collect", "cancel_collect"]:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻数据不存在")

    if action == "collect":
        user.collection_news.append(news)
    else:
        user.collection_news.remove(news)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存失败")

    return jsonify(errno=RET.OK, errmsg="操作成功")


@news_blue.route('/news_comment', methods=['POST'])
@user_login_data
def news_comment():
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    json_data = request.json
    news_id = json_data.get("news_id")
    comment_content = json_data.get("comment")
    parent_id = json_data.get("parent_id")

    if not all([news_id, comment_content]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if comment_content.startswith('$$$isDeleted$$$'):
        return jsonify(errno=RET.PARAMERR, errmsg="含关键字字段")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")

    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news_id
    comment.content = comment_content
    if parent_id:
        comment.parent_id = parent_id

    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存评论数据失败")

    return jsonify(errno=RET.OK, errmsg="评论成功", data=comment.to_dict())


@news_blue.route('/comment_like', methods=['POST'])
@user_login_data
def comment_like():
    if not g.user:
        return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')

    comment_id = request.json.get("comment_id")
    news_id = request.json.get("news_id")
    action = request.json.get("action")

    if action not in ['add', 'remove']:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    if not all([comment_id, news_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='缺少关键参数')

    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询数据失败')

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg='评论数据不存在')

    com_like = CommentLike.query.filter_by(comment_id=comment_id, user_id=g.user.id).first()
    if action == 'add' and not com_like:
        new_comment_like = CommentLike()
        new_comment_like.comment_id = comment_id
        new_comment_like.user_id = g.user.id
        db.session.add(new_comment_like)
        comment.like_count += 1
    elif action == 'remove' and com_like:
        db.session.delete(com_like)
        comment.like_count -= 1

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='操作失败')
    return jsonify(errno=RET.OK, errmsg='操作成功')


@news_blue.route('/followed_user', methods=['POST'])
@user_login_data
def followed_user():
    if not g.user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    user_id = request.json.get("user_id")
    action = request.json.get("action")

    if not all([user_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ['follow', 'unfollow']:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        target_user = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据库失败")

    if not target_user:
        return jsonify(errno=RET.NODATA, errmsg="未查询到用户数据")

    if action == 'follow':
        if target_user.followers.filter(User.id == g.user.id).count() > 0:
            return jsonify(errno=RET.DATAEXIST, errmsg="当前已关注")
        target_user.followers.append(g.user)
    else:
        if target_user.followers.filter(User.id == g.user.id).count() > 0:
            target_user.followers.remove(g.user)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据保存错误")

    return jsonify(errno=RET.OK, errmsg="操作成功")


@news_blue.route('/comment_delete', methods=['POST'])
@user_login_data
def comment_delete():
    if not g.user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    comment_id = request.json.get("comment_id")

    if not comment_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据库失败")

    # 防止误删他人数据
    if comment.user_id != g.user.id and not g.user.is_admin:
        return jsonify(errno=RET.PARAMERR, errmsg="用户错误")

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="未查询到用户数据")

    # 避免对数据库表结构进行改动，采用逻辑删除，内容加上前缀，后面会完善判断逻辑。
    comment.content = "$$$isDeleted$$$" + comment.content

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据保存错误")

    return jsonify(errno=RET.OK, errmsg="操作成功")
